package com.cpedia.android.deal.service;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
import com.cpedia.android.deal.*;
import com.cpedia.android.deal.activity.DealList;

import java.util.HashMap;


/**
 * User: pchen
 * Date: Jun 4, 2009
 */

public class DealService  extends Service {
    private static final String ACTION_CHECK_DEAL = "com.cpedia.android.deal.intent.action.DEAL_SERVICE_WAKEUP";
    private static final String ACTION_RESCHEDULE = "com.cpedia.android.deal.intent.action.DEAL_SERVICE_RESCHEDULE";
    private static final String ACTION_CANCEL = "com.cpedia.android.deal.intent.action.DEAL_SERVICE_CANCEL";

    private Listener mListener = new Listener();

    private int mStartId;

    public static void actionReschedule(Context context) {
        Intent i = new Intent();
        i.setClass(context, DealService.class);
        i.setAction(DealService.ACTION_RESCHEDULE);
        context.startService(i);
    }

    public static void actionCancel(Context context)  {
        Intent i = new Intent();
        i.setClass(context, DealService.class);
        i.setAction(DealService.ACTION_CANCEL);
        context.startService(i);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        this.mStartId = startId;

        DealController controller = DealController.getInstance(getApplication());
        controller.addListener(mListener);
        if (ACTION_CHECK_DEAL.equals(intent.getAction())) {
            if (Config.LOGD && Deal.DEBUG) {
                Log.d(Deal.LOG_TAG, "*** DealService: checking deal");
            }
            controller.checkDeal(this, mListener);
        }
        else if (ACTION_CANCEL.equals(intent.getAction())) {
            if (Config.LOGD && Deal.DEBUG) {
                Log.d(Deal.LOG_TAG, "*** DealService: cancel");
            }
            cancel();
            stopSelf(startId);
        }
        else if (ACTION_RESCHEDULE.equals(intent.getAction())) {
            if (Config.LOGD && Deal.DEBUG) {
                Log.d(Deal.LOG_TAG, "*** DealService: reschedule");
            }
            reschedule();
            stopSelf(startId);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        DealController.getInstance(getApplication()).removeListener(mListener);
    }

    private void cancel() {
        AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent();
        i.setClassName("com.cpedia.android.Deal", "com.cpedia.android.Deal.service.DealService");
        i.setAction(ACTION_CHECK_DEAL);
        PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
        alarmMgr.cancel(pi);
    }

    private void reschedule() {
        AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent();
        i.setClassName("com.cpedia.android.deal", "com.cpedia.android.deal.service.DealService");
        i.setAction(ACTION_CHECK_DEAL);
        PendingIntent pi = PendingIntent.getService(this, 0, i, 0);

        int shortestInterval = -1;
        for (Account account : Preferences.getPreferences(this).getAccounts()) {
            if (account.getAutomaticCheckIntervalMinutes() != -1
                    && (account.getAutomaticCheckIntervalMinutes() < shortestInterval || shortestInterval == -1)) {
                shortestInterval = account.getAutomaticCheckIntervalMinutes();
            }
        }

        if (shortestInterval == -1) {
            alarmMgr.cancel(pi);
        }
        else {
            alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
                    + (shortestInterval * (60 * 1000)), pi);
        }
    }

    public IBinder onBind(Intent intent) {
        return null;
    }

    class Listener extends DealListener {
        HashMap<Account, Integer> hasNewDeal = new HashMap<Account, Integer>();

        @Override
        public void checkDealStarted(Context context) {
            hasNewDeal.clear();
        }

        // Called once per checked account
        @Override
        public void checkDealFailed(Context context, String reason) {
            if (Config.LOGD && Deal.DEBUG) {
                Log.d(Deal.LOG_TAG, "*** DealService: checkDealFailed: " + reason);
            }
            reschedule();
            stopSelf(mStartId);
        }

        // Called once per checked account
        @Override
        public void synchronizDealListFinished(Account account,int totalDeals, int numNewDeals) {
            if (Config.LOGD && Deal.DEBUG) {
                Log.d(Deal.LOG_TAG, "*** DealService: synchronizDealFinished: total=" +
                        totalDeals + " new=" + numNewDeals);
            }
            if (account.isNotifyNewDeal() && numNewDeals > 0) {
                hasNewDeal.put(account, numNewDeals);
            }
        }

        @Override
        public void checkDealFinished(Context context) {
            if (Config.LOGD && Deal.DEBUG) {
                Log.d(Deal.LOG_TAG, "*** DealService: checkDealFinished");
            }
            NotificationManager notifMgr = (NotificationManager)context
                    .getSystemService(Context.NOTIFICATION_SERVICE);

            if (hasNewDeal.size() > 0) {
                Notification notif = new Notification(R.drawable.stat_notify_deal_generic,
                        getString(R.string.notification_new_title), System.currentTimeMillis());
                boolean vibrate = false;
                String ringtone = null;
                
                Account account1 = hasNewDeal.keySet().iterator().next();
                int totalNewDeaks = hasNewDeal.get(account1);
                Intent i = DealList.actionHandleAccountIntent(context, account1);
                PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
                notif.setLatestEventInfo(context, getString(R.string.notification_new_title),
                        getResources().
                                getQuantityString(R.plurals.notification_new_one_account_fmt,
                                totalNewDeaks, totalNewDeaks,
                                ""), pi);
                vibrate = account1.isVibrate();
                ringtone = account1.getRingtone();

                notif.defaults = Notification.DEFAULT_LIGHTS;
                notif.sound = TextUtils.isEmpty(ringtone) ? null : Uri.parse(ringtone);
                if (vibrate) {
                    notif.defaults |= Notification.DEFAULT_VIBRATE;
                }
                notifMgr.notify(1, notif);
            }

            reschedule();
            stopSelf(mStartId);
        }
    }

}